package com.nemodynamic.cattivial.UIElement;

import java.lang.ref.SoftReference;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import java.util.WeakHashMap;

import com.nemodynamic.cattivial.R;
import com.nemodynamic.cattivial.beansElement.CattivialFoodItem;
import com.nemodynamic.cattivial.utils.DLog;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;

public class CattivialFoodItemView extends View {
	private boolean isAnimationStarted = false;
	private static final String TAG = "CattivialFoodItemView";
	private boolean isStarted = false;
	private static boolean isInit = false;
	private static boolean isFinishing = false;
	private CattivialFoodItem food;
	private WeakHashMap<Integer, SoftReference<Bitmap>> mCache;
	private long scheduleTime;
	private Timer timer;
	private TimerTask timerTask;
	private float cicularPulse = 0;
	private Animation eatenAnimation;

	public CattivialFoodItemView(Context context, CattivialFoodItem foodItem) {
		super(context);
		eatenAnimation = AnimationUtils.loadAnimation(context,
				R.anim.item_anim_eaten);
		eatenAnimation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationRepeat(Animation animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationEnd(Animation animation) {
				food.setConsumed(true);
				setVisibility(View.GONE);
			}
		});
		mCache = new WeakHashMap<Integer, SoftReference<Bitmap>>();
		this.food = foodItem;
		int validityTime = foodItem.getValidityTime() * 1000;
		scheduleTime = new Random().nextInt(validityTime);
		DLog.i(TAG, "Timer delay for " + this.getClass().hashCode() + ": "
				+ scheduleTime);
		timer = new Timer();
		timerTask = new TimerTask() {

			@Override
			public void run() {
				if (!food.isEaten() && !food.isToBeDrawn()
					&& !food.isConsumed()) {
					if (new Random().nextBoolean()) {
						DLog.i(TAG, this + " has scheduled his job");
						food.setToBeDrawn(true);
						food.startTimer();
					}
				}
			}
		};

	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (isInit && !isStarted) {
			startCasualDrawing();
		}
		if (isFinishing) {
			stopCasualDrawing();
		}
		
		if (isStarted) {
			cicularPulse += 0.08;
			if (cicularPulse > (2 * Math.PI)) {
				cicularPulse = 0;
			}
			float scale = (float) Math.cos(cicularPulse) * 0.02f + 1f;
			canvas.scale(scale, scale);
			drawFoodItem(canvas, food);
		}
		invalidate();
	}

	private void drawFoodItem(Canvas canvas, CattivialFoodItem foodItem) {
		//DLog.i(TAG, "isToBeDrawn"+ foodItem.isToBeDrawn()+" isConsumed " + foodItem.isConsumed());
		if (foodItem.isToBeDrawn() && !foodItem.isConsumed()) {
			canvas.drawBitmap(get(foodItem.getResourceDrawable()),
					foodItem.getX(), foodItem.getY(), null);
			DLog.i(TAG,"Disegnato " +foodItem.getX() +" "+foodItem.getY() );
		}
		if (foodItem.isEaten() && !isAnimationStarted) {
			DLog.d(TAG, "Animation");
			isAnimationStarted = true;
			startAnimation(eatenAnimation);
		}

	}

	public Bitmap get(int resourceId) {

		if (mCache.containsKey(resourceId)) {
			SoftReference<Bitmap> reference = mCache.get(resourceId);
			Bitmap bitmap = reference.get();
			if (bitmap != null) {
				return bitmap;
			}
			return decodeBitmap(resourceId);
		}
		return decodeBitmap(resourceId);
	}

	private Bitmap decodeBitmap(int resourceId) {
		Bitmap bitmap = BitmapFactory
				.decodeResource(getResources(), resourceId);
		mCache.put(resourceId, new SoftReference<Bitmap>(bitmap));
		return bitmap;
	}

	public void startCasualDrawing() {
		DLog.i(TAG, this.getClass().hashCode() + " has started his job");
		isStarted = true;
		try {
			timer.schedule(timerTask, scheduleTime);
		} catch (Exception e) {
			DLog.e(TAG, "Risolvere il problema del timer");
		}
	}

	public void stopCasualDrawing() {
		
		if (isStarted) {
			DLog.i(TAG, "Stop casual drawing called");
			food.stopTimer();
			timer.cancel();
			isStarted = false;
		}
	}

	public static void start() {
		CattivialFoodItemView.isInit = true;
		CattivialFoodItemView.isFinishing = false;
	}

	public static void stop() {
		DLog.i(TAG, "Stop food called");
		CattivialFoodItemView.isFinishing = true;
		CattivialFoodItemView.isInit = false;
	}
}
